package com.lmx.persistence.service;

import java.util.ArrayList;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.lmx.common.constants.CommonConstants;
import com.lmx.common.context.ActionContextHolder;
import com.lmx.common.util.CommonUtil;
import com.lmx.repoDomain.tmodel.Customer;
import com.lmx.repoDomain.tmodel.CustomerBill;
import com.lmx.repoDomain.tmodel.CustomerBusinessFlow;
import com.lmx.repoDomain.tmodel.CustomerDayBill;
import com.lmx.repoDomain.tmodel.CustomerServiceBill;
import com.lmx.repoDomain.tmodel.Dicttype;
import com.lmx.repoDomain.tmodel.NursingProject;
import com.lmx.repoDomain.tmodel.NursingProjectServiceItem;
import com.lmx.repoDomain.tmodel.RechargeRecord;
import com.lmx.repoDomain.tmodel.TradeAccount;
import com.lmx.repoDomain.tmodel.TradeDetail;
/**
 * 
 * 
 * @author huibati
 * @version 1.00
 */
@Service
@Scope("prototype")
public class AccountService<T> {

	private Log logger = LogFactory.getLog(this.getClass());

	@PersistenceContext
	private EntityManager em;

	@Autowired   
	protected GenericService dslJpaService;

	@Autowired
	protected WorkPlaceService workPlaceService;

	@Autowired
	protected NursingService nursingService;

	@Autowired
	private CommonService commonService;

	// 获取账户
	public TradeAccount getTradeAccountByOrg(Long orgId) {
		TradeAccount cb = (TradeAccount) this.em.createQuery("select c from TradeAccount c where c.org.id = ?1 and c.delStatus != ?2 ")
				.setParameter(1, orgId).setParameter(2, (short)1).getSingleResult();
		return cb;
	}

	// 获取账单
	public CustomerBill getCustomerBillById(CustomerBill bill) {
		CustomerBill cb = (CustomerBill) this.em.createQuery("select c from CustomerBill c where c.id = ?1")
				.setParameter(1, bill.getId()).getSingleResult();
		return cb;
	}

	// 更新账户余额
	@Transactional
	public Double updateAccountBalance(TradeAccount account, Double money) {
		TradeAccount payerAccount = (TradeAccount) this.em.createQuery("select a from TradeAccount a where a.id = ?1 ")
				.setParameter(1, account.getId()).getSingleResult();
		account.setBalance(payerAccount.getBalance() + money);
		dslJpaService.setEntityClass(TradeAccount.class);
		dslJpaService.update(account);
		return account.getBalance();
	}

	// 账单审核通过生成流水记录 更改账户金额
	@Transactional
	public void updateAccountBalanceByBill(Customer customer, CustomerBill bill) {
		int flag = 0;
		List<TradeAccount> acountList = this.em.createQuery("select a from TradeAccount a where a.customer.id = ?1 and a.delStatus != ?2 ")
				.setParameter(1, customer.getId()).setParameter(2, (short)1).getResultList();
		TradeAccount cuEAccount = null;
		TradeAccount cuEnsureAccount = null;
		for (TradeAccount account : acountList) {
			if (CommonConstants.DICTTYPE.ACCOUNT_TYPE_2.label().equals(account.getType().getTypecode())) {
				cuEAccount = account;
			} else {
				cuEnsureAccount = account;
			}
		}

		TradeAccount orgAccount = (TradeAccount) this.em.createQuery("select a from TradeAccount a where a.org.id = ?1 and a.delStatus != ?2 ")
				.setParameter(1, ActionContextHolder.getContext().getUser().getOrg().getId()).setParameter(2, (short)1).getSingleResult();
		TradeDetail detailE = new TradeDetail();
		TradeDetail detailEnsure = null;
		if (cuEAccount.getBalance() >= bill.getTotal()) {
			// 生成扣款流水
			detailE.setMoney(bill.getTotal());
			detailE.setGatherAccount(orgAccount);
			detailE.setPayAccount(cuEAccount);
			detailE.setBalance(cuEAccount.getBalance() - bill.getTotal());
			detailE.setEnSurebalance(cuEnsureAccount.getBalance());
			detailE.setRemark(bill.getRemark());
			// 设置账户余额
			cuEAccount.setBalance(cuEAccount.getBalance() - bill.getTotal());
		} else {
			flag = 1;
			// 生成扣款流水
			detailE.setMoney(cuEAccount.getBalance());
			detailE.setGatherAccount(orgAccount);
			detailE.setPayAccount(cuEAccount);
			detailE.setRemark(bill.getRemark());
			detailE.setBalance(0.0);

			detailEnsure = new TradeDetail();
			detailEnsure.setMoney(cuEAccount.getBalance() - bill.getTotal());
			detailEnsure.setGatherAccount(orgAccount);
			detailEnsure.setPayAccount(cuEnsureAccount);
			detailEnsure.setBalance(cuEAccount.getBalance() - bill.getTotal() + cuEnsureAccount.getBalance());
			detailEnsure.setRemark(bill.getRemark());
			
			detailE.setEnSurebalance(cuEAccount.getBalance() - bill.getTotal() + cuEnsureAccount.getBalance());
			detailEnsure.setEnSurebalance(cuEAccount.getBalance() - bill.getTotal() + cuEnsureAccount.getBalance());
			// 设置账户余额
			cuEnsureAccount.setBalance(cuEAccount.getBalance() - bill.getTotal() + cuEnsureAccount.getBalance());
			cuEAccount.setBalance(0.0);
		}

		orgAccount.setBalance(orgAccount.getBalance() + bill.getTotal());
		dslJpaService.setEntityClass(TradeAccount.class);
		dslJpaService.update(orgAccount);// 更新机构账户余额
		dslJpaService.update(cuEAccount);// 更新电子账户余额
		if (flag == 1) {
			dslJpaService.update(cuEnsureAccount);// 更新保证金账户
		}

		dslJpaService.setEntityClass(TradeDetail.class);
		dslJpaService.create(detailE);// 电子账户流水
		if (flag == 1) {
			dslJpaService.create(detailEnsure);// 保证金账户流水
		}
		if(bill.getFlow()!=null){//退住完成
			dslJpaService.setEntityClass(CustomerBusinessFlow.class);
			bill.getFlow().setLeaveStatus(commonService.getDicttype(CommonConstants.DICTTYPE.FLOW_LEAVE_STATUS_3.label()));
			dslJpaService.update(bill.getFlow());
		}
		dslJpaService.setEntityClass(CustomerBill.class);
	}

	
	/**
	 *   @author huibati
	 *   生成日期当天的日账单
	 *   2017年7月19日 
	 */
	public void createDayBill(Customer customer, String dayTime) {
		logger.info("start create day bill " + CommonUtil.getCurrTimeForString() + " customerid " + customer.getId());
		String year = dayTime.substring(0, 4);
		String month = dayTime.substring(5, 7);
		String bedPrice = "0.0";
		String foodPrice = "0.0";
		String projectPrice = "0.0";

		if (customer.getActualPrice() != null && !"".equals(customer.getActualPrice())) { // 老人实际住宿价格不为空
			CustomerDayBill dayBill = new CustomerDayBill();
			dayBill.setCustomer(customer);
			dayBill.setBillYear(Integer.parseInt(year));
			dayBill.setBillMonth(Integer.parseInt(month));
			dayBill.setTenant(customer.getTenant());
			try {
				dayBill.setBillTime(CommonUtil.strToIntegerTime(dayTime));
				dayBill.setTotal(Double.parseDouble(customer.getActualPrice()));
			} catch (Exception e) {
				logger.debug("createDayBill error " + e);
			}
			if (customer.getActualBedPrice() != null) {
				bedPrice = customer.getActualBedPrice().toString();// workPlaceService.getBed(customer.getBed()).getPrice();
			}
			dayBill.setTotal1(Double.parseDouble(bedPrice));// 床位
			if (customer.getActualDiningPrice() != null) {
				foodPrice = customer.getActualDiningPrice().toString();// customer.getDiningStandard().getTypeValue();
			}
			dayBill.setTotal2(Double.parseDouble(foodPrice));// canyin
			NursingProject project = nursingService.getProjectByCustomer(customer);
			if (project != null && project.getPrice() != null) {
				projectPrice = project.getPrice().toString();
			}
			dayBill.setTotal3(Double.valueOf(projectPrice));// project
			dslJpaService.setEntityClass(CustomerDayBill.class);
			dslJpaService.create(dayBill);
			logger.info("end create day bill " + CommonUtil.getCurrTimeForString() + " customerid " + customer.getId());
		}

	}

	// 生成账单
	@Transactional
	public void createCustomerBill(Customer Customer, Dicttype billType) {
		CustomerBill bill = new CustomerBill();
		dslJpaService.setEntityClass(CustomerBill.class);
		dslJpaService.create(bill);
	}

	/**
	 *   @author huibati
	 *   统计时间段内的日账单生成总账单
	 *   2017年7月19日 
	 */
	public void createCustomerBill(Customer customer, Integer startTime, Integer endTime,CustomerBusinessFlow flow) {
		logger.info("start create bill "+CommonUtil.getCurrTimeForString()+" customerid "+customer.getId());
		List<CustomerBill> dataList = new ArrayList<>();
		String date=CommonUtil.integetTimeForString(startTime);
		//统计日账单
		Double total1 = 0.0;
		Double total2 = 0.0;
		Double total3 = 0.0;
		Double total = 0.0;
		List<CustomerDayBill> dayBillList = this.em
				.createQuery(
						"select a from CustomerDayBill a where a.delStatus != 1 and a.customer.id = ?1 and a.billTime >=?2 and a.billTime <?3 ")
				.setParameter(1, customer.getId()).setParameter(2, startTime).setParameter(3, endTime).getResultList();
		for (CustomerDayBill dayBill : dayBillList) {
			if (dayBill != null) {
				total1 += dayBill.getTotal1();
				total2 += dayBill.getTotal2();
				total3 += dayBill.getTotal3();
				total += dayBill.getTotal();
			}
		}
		CustomerBill bill = new CustomerBill();
		//设置月账单类型
		bill.setBillMonth(Integer.parseInt(date.substring(5, 7)));
		bill.setBillYear(Integer.parseInt(date.substring(0, 4)));
		bill.setCustomer(customer);
		bill.setTenant(customer.getTenant());
		bill.setTotal(total);
		bill.setTotal1(total1);
		bill.setTotal2(total2);
		bill.setTotal3(total3);
		bill.setDelStatus((short)0);
		bill.setBillStatus(commonService.getDicttype(CommonConstants.DICTTYPE.BILL_STATUS_1.label()));// 已经提交
		bill.setBillStatType(commonService.getDicttype("billStatTypeJC"));//基础服务统计
		bill.setBillType(commonService.getDicttype(CommonConstants.DICTTYPE.BILL_TYPE_2.label()));//月账单
		bill.setBillCreateType(commonService.getDicttype("createType1"));//系统生成
		bill.setBillTime(startTime);// 当月第一天时间
		if (flow != null) {
			bill.setFlow(flow);
		}
		dataList.add(bill);
		//统计增值服务账单
		List<CustomerServiceBill> serviceBillList = this.em
				.createQuery(
						"select a from CustomerServiceBill a where a.delStatus != 1 and a.customer.id = ?1 and a.billTime >=?2 and a.billTime <?3 ")
				.setParameter(1, customer.getId()).setParameter(2, startTime).setParameter(3, endTime).getResultList();
		Double ZZTotal = 0.0;
		for (CustomerServiceBill serviceBill : serviceBillList) {
			if (serviceBill != null) {
				ZZTotal += serviceBill.getTotal();
			}
		}
		CustomerBill serviceBill = new CustomerBill();
		//设置月账单类型
		serviceBill.setBillMonth(Integer.parseInt(date.substring(5, 7)));
		serviceBill.setBillYear(Integer.parseInt(date.substring(0, 4)));
		serviceBill.setCustomer(customer);
		serviceBill.setTenant(customer.getTenant());
		serviceBill.setTotal(ZZTotal);
		serviceBill.setDelStatus((short) 0);
		serviceBill.setBillStatus(commonService.getDicttype(CommonConstants.DICTTYPE.BILL_STATUS_1.label()));// 已经提交
		serviceBill.setBillStatType(commonService.getDicttype("billStatTypeZZ"));//增值服务统计
		serviceBill.setBillTime(startTime);// 当月第一天时间 
		serviceBill.setBillType(commonService.getDicttype(CommonConstants.DICTTYPE.BILL_TYPE_2.label()));//月账单
		serviceBill.setBillCreateType(commonService.getDicttype("createType1"));//系统生成
		dataList.add(serviceBill);
		//批量增添
		commonService.batchInsert(dataList);
		logger.info("end create bill "+CommonUtil.getCurrTimeForString());
	}
	
	public void createRechargeRecord(RechargeRecord record){
		dslJpaService.setEntityClass(RechargeRecord.class);
		dslJpaService.create(record);
	}
	
	public TradeAccount findOrgAccountByOrg(Long orgId) {
		TradeAccount orgAccount = null;
		orgAccount = (TradeAccount) this.em.createQuery("select a from TradeAccount a where a.org.id = ?1 and a.delStatus!=?2 ")
				.setParameter(1, orgId).setParameter(2, (short)1).getSingleResult();
		return orgAccount;
	}
}
